package com.totoro.rabbitmq.PTP;

import com.rabbitmq.client.*;
import com.totoro.rabbitmq.RabbitMQUtil;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 一个发送者，多个接收者客户端
 * 为了消息不丢失，我们手动设置ack
 * 多个接收者可以避免当一个接收者宕机后，队列无人消费，提高系统的可用性
 * 多个接收者也可以对消息进行负载，使得系统性能更好
 * Created by Niki on 2018/3/29 7:44
 */
public class PTPMoreClient {
    private static String queue_name = "hello_demo2_queue";

    private static void receiveMsg(){
        ConnectionFactory connectionFactory = RabbitMQUtil.getConnectionFactory();
        Connection connection = null;
        Channel channel = null;
        try {
            connection = connectionFactory.newConnection();
            channel = connection.createChannel();

            /*
                * 一次只处理一个消息，消息没有处理完则不接收后面的消息。
                * 当多个consumer时，Service也会根据Consumer的空闲情况进行负载。如果性能好的consumer可以设置大的接收量
             */
            channel.basicQos(1);

            //声明队列 queue_name 与服务端名称一致
            channel.queueDeclare(queue_name, true, false, false, null);

            //创建客户端
            Consumer consumer = new DefaultConsumer(channel){
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                    String msg = new String(body, "utf-8");
                     long deliveTag = envelope.getDeliveryTag();
                     //手动确认事务ack
                     getChannel().basicAck(deliveTag, false);

                     //取消订阅
//                    getChannel().basicCancel(consumerTag);
                }
            };
            //设置客户端，并且不自动ack
            channel.basicConsume(queue_name, false, consumer);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }finally {
            RabbitMQUtil.closeChannel(channel);
            RabbitMQUtil.closeConnection(connection);
        }
    }
}
